package com.xiaozhu.service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.xiaozhu.common.constant.GaoDeUrl;
import com.xiaozhu.common.constant.RestaurantAddress;
import com.xiaozhu.common.constant.WeightedConstant;
import com.xiaozhu.pojo.dto.UserDto;
import com.xiaozhu.pojo.entity.User;
import com.xiaozhu.pojo.vo.UserVo;
import com.xiaozhu.service.MapService;
import com.xiaozhu.utils.HttpClientUtils;
import com.xiaozhu.utils.algorithm.RouteSelector;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 朱慧军
 * @version 1.0
 */
@Service
@Slf4j
public class MapServiceImpl implements MapService {

    @Value("${xiaozhu.gaode.ak}")
    private String gaode_ak;

    @Override
    public UserVo distance(UserDto userDto) {
        log.info("接收到用户请求: {}", JSON.toJSONString(userDto));

        // 1️⃣ 解析用户地址 → 经纬度
        String userLatLng = resolveAddress(userDto.getAddress());
        if (userLatLng == null) {
            log.error("用户地址解析失败: {}", userDto.getAddress());
            return null; // 或者抛异常
        }
        log.info("用户经纬度: {}", userLatLng);

        // 2️⃣ 解析餐厅地址 → 经纬度
        String restaurantLatLng = resolveAddress(RestaurantAddress.RESTAURANT_PATH);
        if (restaurantLatLng == null) {
            log.error("餐厅地址解析失败: {}", RestaurantAddress.RESTAURANT_PATH);
            return null;
        }
        log.info("餐厅经纬度: {}", restaurantLatLng);

        // 3️⃣ 调用高德驾车路线 API
        JSONObject routeJson = drivingRoute(userLatLng, restaurantLatLng);
        if (routeJson == null) {
            log.error("获取路线失败");
            return null;
        }

        JSONArray paths = routeJson.getJSONArray("paths");
        if (paths == null || paths.isEmpty()) {
            log.error("没有可用路线");
            return null;
        }

        // 4️⃣ 使用加权算法选择最优路线
        JSONObject optimalRouteJson = RouteSelector.selectBestByWeightedScore(
                paths,
                WeightedConstant.WEIGHTED_DISTANCE,
                WeightedConstant.WEIGHTED_DURATION,
                WeightedConstant.WEIGHTED_SPEND
        );

        // 5️⃣ 从最优路线中获取关键数据
        double distance = optimalRouteJson.getDoubleValue("distance");  // 距离，单位：米
        double duration = optimalRouteJson.getDoubleValue("duration");  // 时间，单位：秒
        JSONArray steps = optimalRouteJson.getJSONArray("steps");       // 路径详细步骤

        // 6️⃣ 将每一步的 polyline 拼接为路径点列表
        List<String> pathPoints = steps == null ? Collections.emptyList() :
                steps.stream()
                        .map(obj -> ((JSONObject) obj).getString("polyline")) // 每一步的经纬度坐标
                        .toList();

        // 7️⃣ 构建描述字符串
        String optimalRouteDesc = String.format("最优路线：距离 %.2f 米，耗时 %.2f 秒", distance, duration);

        // 8️⃣ 构建 UserVo 并返回
        return UserVo.builder()
                .distance(distance)
                .addressInfo(optimalRouteDesc)               // 最优路线描述
                .route(String.join(";", pathPoints))        // 所有路径点，用分号分隔
                .drivingLicense(optimalRouteJson)           // 整个最优路线 JSON 对象
                .build();
    }

    /**
     * 地址解析 → 经纬度
     */
    private String resolveAddress(String address) {
        Map<String, String> params = new HashMap<>();
        params.put("address", address);
        params.put("output", "json");
        params.put("key", gaode_ak);

        String response = HttpClientUtils.doGet(GaoDeUrl.ADDRESS_API, params);
        if (response == null || response.isBlank()) {
            log.error("地址解析返回为空: {}", address);
            return null;
        }

        JSONObject jsonObject = JSON.parseObject(response);
        if (!"1".equals(jsonObject.getString("status"))) {
            log.error("地址解析失败: {}, 响应信息: {}", address, jsonObject);
            return null;
        }

        JSONObject geocode = jsonObject.getJSONArray("geocodes").getJSONObject(0);
        return geocode.getString("location"); // 返回 "lng,lat"
    }

    /**
     * 调用高德地图 驾车路线规划 API
     */
    private JSONObject drivingRoute(String origin, String destination) {
        Map<String, String> params = new HashMap<>();
        params.put("origin", origin);
        params.put("destination", destination);
        params.put("key", gaode_ak);
        params.put("extensions", "all"); // 注意这里是 extensions，不是 extension

        String response = HttpClientUtils.doGet("https://restapi.amap.com/v3/direction/driving", params);
        if (response == null || response.isBlank()) {
            log.error("驾车路线返回为空, origin={}, destination={}", origin, destination);
            return null;
        }

        JSONObject json = JSON.parseObject(response);
        if (!"1".equals(json.getString("status"))) {
            log.error("路线规划失败: {}, {}", json.getString("info"), json.getString("infocode"));
            return null;
        }

        return json.getJSONObject("route");
    }
}
